package command;

import parser.ChessContentHandlerConstants;
import parser.ParserConstants;


/*
 * This class will help keep track of an attack
 * @author Max Joyce (Feb 9, 2010)
 */
public class AttackCommand implements Command {

	protected chess.Tile destTile;
	protected chess.Tile origTile;
	protected chess.Piece pieceKilled;
	protected chess.Player killingPlayer;
	protected boolean movedPreviously;
	protected Command		secondaryCommand;
	
	/*
	 * Constructs the AttackCommand with the original and destination tiles
	 * as well as the piece killed
	 * This class is immutable.
	 * 
	 * <pre>
	 * Max Joyce
	 * -Created class (Feb 9th, 2010)
	 * </pre>
	 */
	public AttackCommand(chess.Tile orig, chess.Tile dest, chess.Player curPlayer){
		this.destTile=dest;
		this.origTile=orig;
		pieceKilled=destTile.getPieceHere();
		killingPlayer = curPlayer;
		this.movedPreviously=this.origTile.getPieceHere().hasMoved();
		secondaryCommand = new NoSecondaryCommand();
	}
	
	@Override
	/*
	 * Performs the attack
	 * <pre>
	 * Max Joyce
	 * -Created (Feb 9, 2010)
	 * </pre>
	 */
	public void execute() {
		this.origTile.getPieceHere().setMoved(true);
		pieceKilled.die();
		this.killingPlayer.addKill(pieceKilled);
		this.origTile.getPieceHere().move(destTile);
		secondaryCommand.execute();


	}

	@Override
	/*
	 * Undoes the attack
	 * <pre>
	 * Max Joyce
	 * -Created (Feb 9, 2010)
	 * </pre>
	 */
	public void undo() {
		secondaryCommand.undo();
		this.destTile.getPieceHere().move(origTile);
		this.killingPlayer.getKills().remove(pieceKilled);
		destTile.setPieceHere(pieceKilled);
		pieceKilled.setCurrentTile(destTile);
		this.origTile.getPieceHere().setMoved(movedPreviously);
	}

	/*
	 * Outputs the command as a string for output
	 * <pre>
	 * Max Joyce
	 * -Created (Feb 9, 2010)
	 * </pre>
	 */
	public String toString(){
		String output="";
		
		output+="Attack: "+origTile.toString()+" to "+destTile.toString()+" killing ";
		output+=pieceKilled.toString();
		
		return output;
	}
	
	/**
	 * Allows the addition of a secondary command such as a castle move or a promotion
	 * <pre>
	 * Max Joyce
	 * -Created (Feb 17, 2010)
	 * </pre>
	 */
	public void addSecondaryCommand(Command secondaryCommand){
		if (this.secondaryCommand instanceof NoSecondaryCommand){
			this.secondaryCommand = secondaryCommand;
		}
		else{
			this.secondaryCommand.addSecondaryCommand(secondaryCommand);
		}
		
	}
	
	public boolean hadMovedPreviously(){
		return movedPreviously;
	}
	
	public chess.Tile getOrigTile(){
		return this.origTile;
	}
	
	public chess.Tile getDestTile(){
		return this.destTile;
	}
	/**
	 * This method will return a string representation of the command used for importing and
	 * exporting
	 * @return Returns a string representing the object
	 */
	public String exportCode(){
		return "Attack:"+origTile.toString()+"to"+destTile.toString() + "with" + this.secondaryCommand.exportCode();
	}
	/**
	 * This method will return a string representation of the command used for saving and
	 * loading
	 * @return Returns a string representing the object
	 */
	public String xmlCode(){
		String code = "<" + ParserConstants.ELEMENT_ATTACK + ">\n";
		
		code += "\t" + origTile.XMLPointTag(ChessContentHandlerConstants.POINT_1).replaceAll("\n", "\n\t");
		code += "\n";
		code += "\t" + destTile.XMLPointTag(ChessContentHandlerConstants.POINT_2).replaceAll("\n", "\n\t");
		code += "\n";
		code += "</" + ParserConstants.ELEMENT_ATTACK + ">\n";
		code += secondaryCommand.xmlCode();
		return code;
	}

	@Override
	public Command getSecondaryCommand() {
		return secondaryCommand;
	}
}
